/*
 * communication.c
 *
 * Created: 2014-01-09 10:17:58
 *  Author: Johan
 */ 

#include "usart_driver.h"
#include "sensor.h"
#include "communication.h"
#include <string.h>
#include <stdbool.h>

#define USART USARTC0

void check_command(char* command, int value);
void data_command(void);
void receive(void);
void parse_command(char* command);
void parse_command2(char* command);
void send(char* send_data);

/*! USART data struct used. */
USART_data_t USART_data;

void send(char* send_data){
	int i = 0;
	while (send_data[i] != '\0') {
		bool byteToBuffer;
		byteToBuffer = USART_TXBuffer_PutByte(&USART_data, send_data[i]);
		if(byteToBuffer){
			i++;
		}
	}
}

void receive(void){
	int size = 1;
	char latest = 'a';
	char* cmd = malloc(sizeof(char)*10);
	/* Fetch received data as it is received. */
	while (1) {
		if (USART_RXBufferData_Available(&USART_data)) {
			if(size >= 9){
				char * tmp = realloc(cmd, (size*2)*sizeof(char));
				if(tmp != NULL) cmd = tmp;
			}
			
			latest = USART_RXBuffer_GetByte(&USART_data);
			cmd[size - 1] = latest;
			if(latest == '\n'){
				parse_command(cmd);
				free(cmd);
				break;
			}
			size++;
		}
	}
}
/*Parses the command and checks if it is containing any numbers*/
void parse_command(char * command)
{
	bool is_cmd = true;
	char* cmd = calloc(20,sizeof(char));
	char* value = calloc(20, sizeof(char));
	
	int value_nbr = 0;
	int i = 0;
	int j = 0;
	//Splitting command if it contains numbers
	while(command[i] != '\n'){
		if(command[i] == ','){ //If it is a ',' change to saving into value
			is_cmd = false;
		}else{
			if(is_cmd){
				cmd[i] = command[i];
				
				}else{
				value[j] = command[i];	
				j++;
			}
		}
		i++;
	}
	cmd[i+1] = '\0';
	value[j] = '\0';
	if(!is_cmd){
		
		value_nbr = atoi(value);
	
	}
	check_command(cmd,value_nbr);
	free(cmd);
	free(value);
}
/* Function for checking what command was received*/
void check_command(char* command, int value){
	if (strcmp(command, data_cmd_rec) == 0)
	{
		data_command();
	}
	else if(strcmp(command, run_cmd_rec) == 0)
	{
		start_sampling();
		send(ok_cmd_send);
	}
	else if(strcmp(command, stop_cmd_rec) == 0)
	{
		stop_sampling();
		send(new_line_send);
	}
	else if(strcmp(command, sample_cmd_rec) == 0)
	{
		sensor_data[1] = value;
		send(ok_cmd_send);
	}
	else if(strcmp(command, rate_cmd_rec) == 0)
	{
		sensor_data[4] = value;
		send(ok_cmd_send);
	}else if(strcmp(command, d_cmd_rec) == 0){
		send(ok_cmd_send);
		send(new_line_send);
		send(date_cmd_send);
		data_command();
	}else if(strcmp(command, e_cmd_rec) == 0){
		send(date_cmd_send);
		data_command();
	}else if(strcmp(command, s_cmd_rec) == 0){
		sensor_data[3] = 999;
	}else{
		send(err_send);
	}
}

//Handle the data command.
void data_command()
{
	int i = 0;
	send(data_cmd_send); //send the data command
	
	while(i < MAX_NUMBER_OF_SENSORS) //loop through all of the sensor data
	{
		char buffer[7];
		itoa(sensor_data[i], buffer, 10); //convert the 16 bit int data to chars
		i++;
		send(buffer); //send the data chars
		send(space_send); //send a space character
	}
	send(end_cmd_send);
}

void init_variables(void){
	int i = 0;
	while(i < MAX_NUMBER_OF_SENSORS){
		sensor_data[i] = 10;
		i++;
	}
	
	data_cmd_send = "DATA:\n";
	ok_cmd_send = "OK";
	end_cmd_send = "END";
	space_send = " ";
	new_line_send = "\n";
	date_cmd_send = "Clock: 12:49:10, Date:1/1, Year:2001\n";
	
	data_cmd_rec = "[data";
	rate_cmd_rec = "[rate";
	stop_cmd_rec = "[stop";
	run_cmd_rec = "[run";
	sample_cmd_rec = "[sample";
	d_cmd_rec = "[d"; 
	e_cmd_rec = "[e"; //same inte ok, \n
	s_cmd_rec = "[s";
	err_send = "ERR";
}
void init_uart(void){
	
	/* PC3 (TXD0) as output. */
	PORTC.DIRSET   = PIN3_bm;
	/* PC2 (RXD0) as input. */
	PORTC.DIRCLR   = PIN2_bm;
	/* Use USARTC0 and initialize buffers. */
	USART_InterruptDriver_Initialize(&USART_data, &USART, USART_DREINTLVL_MED_gc);

	/* USARTC0, 8 Data bits, No Parity, 1 Stop bit. */
	USART_Format_Set(USART_data.usart, USART_CHSIZE_8BIT_gc,
	USART_PMODE_DISABLED_gc, false);

	/* Enable RXC interrupt. */
	USART_RxdInterruptLevel_Set(USART_data.usart, USART_RXCINTLVL_MED_gc);

	/* Set Baudrate to 9600 bps:
	* Use the default I/O clock frequency that is 2 MHz.
	*
	* Baudrate select = (1/(16*(((I/O clock frequency)/Baudrate)-1)
	*                 = 12
	*/
	USART_Baudrate_Set(&USART, 12 , 0);

	/* Enable both RX and TX. */
	USART_Rx_Enable(USART_data.usart);
	USART_Tx_Enable(USART_data.usart);

}
/*! \brief Receive complete interrupt service routine.
*
*  Receive complete interrupt service routine.
*  Calls the common receive complete handler with pointer to the correct USART
*  as argument.
*/
ISR(USARTC0_RXC_vect)
{
	USART_RXComplete(&USART_data);
}


/*! \brief Data register empty  interrupt service routine.
*
*  Data register empty  interrupt service routine.
*  Calls the common data register empty complete handler with pointer to the
*  correct USART as argument.
*/
ISR(USARTC0_DRE_vect)
{
	USART_DataRegEmpty(&USART_data);
}
